<html>
<head>
</head>
<body>
<button onclick="go()">go</button>
<div id="res">&nbsp;</div>
<canvas id="myCanvas" width="1000" height="1000" ></canvas>

</body>
<script>

var MAX_HEIGHT=5; //高
var MAX_WIDTH=5; //宽
var DISABLE_POINT = [0,1]; //屏蔽点
var START_POINT = [0,0];   //起点  屏蔽点的位置决定了[0,0] 必然是起点
var DELAYED = 0;           //每次寻址延时毫秒，降速提高展示效果
    

function equals(point,_point){
    if(point[0]==_point[0] && point[1]==_point[1]){
        return true;
    }else{
        return false;
    }
}

function drawPoint(context,point0,style){
    context.beginPath();
    context.arc(point0[1]*50+25,point0[0]*50+25,3,0,360,false);
    context.fillStyle=style;
    context.fill();
    context.closePath();
}
function drawLine(context,point0,point1,style){
    context.moveTo(point0[1]*50+25,point0[0]*50+25);
    context.lineTo(point1[1]*50+25,point1[0]*50+25);
    context.stroke();
    drawPoint(context,point0,style);
    drawPoint(context,point1,style);
}

function showImage(stack){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d"); 　
    context.clearRect(0,0,1000,1000);
    for(var i=0;i<MAX_HEIGHT;i++){
        for(var j=0;j<MAX_WIDTH;j++){
            drawPoint(context,[i,j],"black");
        }
    }
    drawPoint(context,DISABLE_POINT,"red");
    var lastpoint = START_POINT;
    for(var index =0;index<stack.length;index++){
        var _point = stack[index];
        if(!equals(lastpoint,_point)){
            drawLine(context,lastpoint,_point,"black")
        }
        lastpoint = _point;
    }

}

function show(stack){
    // var str="";
    // for(var index =0;index<stack.length;index++){
    //     var _point = stack[index];
    //     str+=_point[0]+","+_point[1]+" ";
    // }
    // console.log(str);
    showImage(stack);
}

//检查点的有效性
function checkPoint(point,stack){
    if( point[0]<0 || point[0]>=MAX_HEIGHT || point[1]<0 || point[1]>=MAX_WIDTH ){ //过界
        return false;
    }
    if(equals(point,DISABLE_POINT)){         //屏蔽点
        return false;
    }
    for(var index =0;index<stack.length;index++){           //路劲栈中的点
        var _point = stack[index];
        if(point[0]==_point[0] && point[1]==_point[1]){
            return false;
        }
    }
    return true;
}

//按方向探测 0上 1右 2下 3左
function findNextDirect(stack,direct,cg){   
    var currentPoint = stack[stack.length-1];
    var nextPoint;
    if(direct==0){
        nextPoint = [currentPoint[0]-1,currentPoint[1]];
    }else if(direct==1){
        nextPoint = [currentPoint[0],currentPoint[1]+1];
    }else if(direct==2){
        nextPoint = [currentPoint[0]+1,currentPoint[1]];
    }else if(direct==3){
        nextPoint = [currentPoint[0],currentPoint[1]-1];
    }else{
        cg(false);
        return;
    }
    if(checkPoint(nextPoint,stack)){
        stack.push(nextPoint);
        findNext(stack,function(res){
            if(res){
                cg(res);
            }else{
                stack.pop();
                findNextDirect(stack,direct+1,cg);
            }
        });
    }else{
        findNextDirect(stack,direct+1,cg);
    }
}

//探测下一个
function findNext(stack,cg){
    setTimeout(() => {  //让出线程便于图像绘制，导致后面递归需要异步
        show(stack);
        if(stack.length==0){ //路径栈退空，表示找不到正确路径
            cg(false);
            return;
        } 
        if(stack.length==((MAX_HEIGHT*MAX_WIDTH)-1)){ //路劲栈数量和黑点数一样，此时已经连通
            cg(true);
            return;
        } 
        findNextDirect(stack,0,cg);         //开始朝具体方向探测
    }, DELAYED);
}


function go(){
    var stack = [];
    
    stack.push(START_POINT);

    findNext(stack,function(res){
        setTimeout(() => {
            if(!res){
                document.getElementById("res").innerHTML = "找不到路径";
            }else{
                document.getElementById("res").innerHTML = "完成";
            }
        },200);
    });
}


showImage([]); //初始展示点整阵

</script>
</html>